package devdoo.mb
{
	import flash.events.Event;
	
	import mx.events.EffectEvent;
	
	import spark.components.Group;
	import spark.components.TileGroup;
	import spark.effects.Animate;
	import spark.effects.AnimateFilter;
	import spark.effects.Fade;
	import spark.effects.Move;
	import spark.effects.animation.MotionPath;
	import spark.effects.animation.SimpleMotionPath;
	import spark.effects.easing.IEaser;
	import spark.filters.BlurFilter;
	
	public class UseMenuIcons
	{
		//----------------------------------
		//  _elementList
		//----------------------------------
		/**
		 *  Recebe a lista de posição original dos componentes
		 */
		private var _elementList:Array;
		
		//----------------------------------
		//  _move
		//----------------------------------
		/**
		 *  Objeto de animação
		 */
		private var _move:Move;
		
		//----------------------------------
		//  _partTime
		//----------------------------------
		/**
		 *  Parte do tempo total da animação
		 */		
		private var _partTime:Number;
		
		//----------------------------------
		//  _time
		//----------------------------------
		/**
		 *  Tempo atual da animação
		 */				
		private var _time:Number;
		
		//----------------------------------
		//  _animateFilter
		//----------------------------------
		/**
		 *  Filtro de animação
		 */		
		private var _animateFilter:AnimateFilter;
		
		//----------------------------------
		//  _blurFilter
		//----------------------------------
		/**
		 *  Filtro blur
		 */			
		private var _blurFilter:BlurFilter;

		//----------------------------------
		//  _fade
		//----------------------------------
		/**
		 *  Filtro fade
		 */				
		private var _fade:Fade;

		//----------------------------------
		//  UseMenuIcons
		//----------------------------------
		/**
		 *  Construtor
		 *  
		 *  @param elementList Lista de elementos que devem receber animações
		 * 	@return void
		 */		
		public function UseMenuIcons(elementList:Array)
		{
			//Cria lista de posição original dos botões 
			this._elementList = [];
			for each(var el:* in elementList){
				this._elementList.push( {'el':el, 'x':el.x, 'y':el.y} );
				el.visible = false;
			}
		}
		
		//----------------------------------
		//  hideHorizontal
		//----------------------------------
		/**
		 *  Executa animação para ocultar todos os icones do menu.
		 * 
		 *  @return void
		 */	
		public function hideHorizontal(finish:Number, duration:Number, eventStart:Function = null, eventEnd:Function = null, easer:IEaser = null):void
		{
			this._partTime		= (duration / this._elementList.length)/2; 
			this._time 			= duration - this._partTime;
			this._blurFilter	= new BlurFilter(15, 0);
			
			var len:Number	= this._elementList.length-1;
			
			//Cria eventos de animação para cada elemento da lista			
			for (var i:Number = 0; i <= len; i++) 
			{
				var item:* = this._elementList[i];
				item.el.y = item.y;
					
				this._time = this._time-this._partTime;
				this._move = new Move(item.el);
				this._move.xFrom = item.el.x;
				this._move.xTo = finish;
				this._move.duration = this._time;
				this._move.easer = easer;
				
				//Verifica se recebeu evento de inicio
				if(eventStart != null && i == 0)
				this._move.addEventListener(EffectEvent.EFFECT_START, eventStart);
				
				//Verifica se recebeu evento de conclusão
				if(eventEnd != null && i == len)
				this._move.addEventListener(EffectEvent.EFFECT_END, eventEnd);
				
				this._move.play();
				
				this._animateFilter = new AnimateFilter(item.el, this._blurFilter);
				this._animateFilter.duration = this._time;
				this._animateFilter.play();
				
				this._fade = new Fade(item.el);
				this._fade.alphaFrom = 1;
				this._fade.alphaTo = 0;
				this._fade.duration = this._time;
				this._fade.play();
			}
		}
		
		//----------------------------------
		//  showHorizontal
		//----------------------------------
		/**
		 *  Executa animação para mostrar todos os icones do menu.
		 * 
		 *  @return void
		 */		
		public function showHorizontal(begin:Number, duration:Number, eventStart:Function = null, eventEnd:Function = null, easer:IEaser = null):void
		{
			this._partTime = (duration / this._elementList.length)/2; 
			this._time = duration + this._partTime;
			this._blurFilter = new BlurFilter(15, 0);
			
			var len:Number	= this._elementList.length-1;
			
			//Cria eventos de animação para cada elemento da lista			
			for (var i:Number = 0; i <= len; i++) 
			{
				var item:* = this._elementList[i];
				
				this._time = this._time-this._partTime;
				item.el.visible = true;
				item.el.y = item.y;
			
				this._move = new Move(item.el);
				this._move.xFrom = begin;
				this._move.xTo = item.x;
				this._move.duration = this._time;
				this._move.easer = easer;
				
				//Verifica se recebeu evento de inicio
				if(eventStart != null && i == 0)
					this._move.addEventListener(EffectEvent.EFFECT_START, eventStart);
				
				//Verifica se recebeu evento de conclusão
				if(eventEnd != null && i == len)
					this._move.addEventListener(EffectEvent.EFFECT_END, eventEnd);
				
				this._move.play();
				
				this._animateFilter = new AnimateFilter(item.el, this._blurFilter);
				this._animateFilter.duration = this._time;
				this._animateFilter.play();	
				this._fade = new Fade(item.el);
				this._fade.alphaFrom = 0;
				this._fade.alphaTo = 1;
				this._fade.duration = this._time;
				this._fade.play();						
			}			
		}

		//----------------------------------
		//  hideVertical
		//----------------------------------
		/**
		 *  Executa animação para ocultar todos os icones do menu.
		 * 
		 *  @return void
		 */	
		public function hideVertical(finish:Number, duration:Number, eventStart:Function = null, eventEnd:Function = null, easer:IEaser = null):void
		{
			this._partTime = (duration / this._elementList.length)/2; 
			this._time = duration - this._partTime;
			this._blurFilter = new BlurFilter(0, 10);
			
			var len:Number	= this._elementList.length-1;
			
			//Cria eventos de animação para cada elemento da lista			
			for (var i:Number = 0; i <= len; i++) 
			{
				var item:* = this._elementList[i];
				item.el.x = item.x;
				
				this._time = this._time-this._partTime;
				this._move = new Move(item.el);
				this._move.yFrom = item.el.y;
				this._move.yTo = finish;
				this._move.duration = this._time;
				this._move.easer = easer;
				
				//Verifica se recebeu evento de inicio
				if(eventStart != null && i == 0)
					this._move.addEventListener(EffectEvent.EFFECT_START, eventStart);
				
				//Verifica se recebeu evento de conclusão
				if(eventEnd != null && i == len)
					this._move.addEventListener(EffectEvent.EFFECT_END, eventEnd);
				
				this._move.play();
				
				this._animateFilter = new AnimateFilter(item.el, this._blurFilter);
				this._animateFilter.duration = this._time;
				this._animateFilter.play();	
				
				this._fade = new Fade(item.el);
				this._fade.alphaFrom = 1;
				this._fade.alphaTo = 0;
				this._fade.duration = this._time;
				this._fade.play();
			}			
		}		
		
		//----------------------------------
		//  showVertical
		//----------------------------------
		/**
		 *  Executa animação para mostrar todos os icones do menu.
		 * 
		 *  @return void
		 */		
		public function showVertical(begin:Number, duration:Number, eventStart:Function = null, eventEnd:Function = null, easer:IEaser = null):void
		{
			this._partTime = (duration / this._elementList.length)/2; 
			this._time = duration + this._partTime;
			this._blurFilter = new BlurFilter(0, 10);
			
			var len:Number	= this._elementList.length-1;
			
			//Cria eventos de animação para cada elemento da lista			
			for (var i:Number = 0; i <= len; i++) 
			{
				var item:* = this._elementList[i];
				this._time = this._time-this._partTime;
				item.el.visible = true;
				item.el.x = item.x;
					
				this._move = new Move(item.el);
				this._move.yFrom = begin;
				this._move.yTo = item.y;
				this._move.duration = this._time;
				this._move.easer = easer;
				
				//Verifica se recebeu evento de inicio
				if(eventStart != null && i == 0)
					this._move.addEventListener(EffectEvent.EFFECT_START, eventStart);
				
				//Verifica se recebeu evento de conclusão
				if(eventEnd != null && i == len)
					this._move.addEventListener(EffectEvent.EFFECT_END, eventEnd);
				
				this._move.play();
				
				this._animateFilter = new AnimateFilter(item.el, this._blurFilter);
				this._animateFilter.duration = this._time;
				this._animateFilter.play();	
				
				this._fade = new Fade(item.el);
				this._fade.alphaFrom = 0;
				this._fade.alphaTo = 1;
				this._fade.duration = this._time;
				this._fade.play();						
			}			
		}
		
		//----------------------------------
		//  tileAnimate
		//----------------------------------
		/**
		 *  Executa animação de icones em componentes tileGroup
		 * 
		 *  @return void
		 */		
		private var _group:Group;
		public function tileAnimate(target:TileGroup, endTarget:Group, duration:Number, eventStart:Function = null, eventEnd:Function = null):void
		{
			this._group = endTarget;
			
			var verticalGap:SimpleMotionPath = new SimpleMotionPath();
				verticalGap.valueFrom = 100;
				verticalGap.valueTo = 23;
				verticalGap.property = "verticalGap";
			
			var horizontalGap:SimpleMotionPath = new SimpleMotionPath();
				horizontalGap.valueFrom = 100;
				horizontalGap.valueTo = 23;
				horizontalGap.property = "horizontalGap";
			
			var alpha:SimpleMotionPath = new SimpleMotionPath();
				alpha.valueFrom = 100;
				alpha.valueTo = 23;
				alpha.property = "alpha";
			
			var vector:Vector.<MotionPath> = new Vector.<MotionPath>;
				vector.push( verticalGap );
				vector.push( horizontalGap );
				vector.push( alpha );
			
			var animate:Animate = new Animate(target);
				animate.duration = duration;
				animate.motionPaths = vector;
				//Verifica se recebeu evento de inicio
				if(eventStart != null && i == 0)
					animate.addEventListener(EffectEvent.EFFECT_START, eventStart);
				
				//Verifica se recebeu evento de conclusão
				if(eventEnd != null && i == len)
					animate.addEventListener(EffectEvent.EFFECT_END, eventEnd);
					animate.addEventListener(EffectEvent.EFFECT_END, addGroup);
					
				animate.play();
				
			var len:Number	= this._elementList.length-1;	
				
			
			//Cria eventos de animação para cada elemento da lista			
			for (var i:Number = 0; i <= len; i++) 
			{
				var item:* = this._elementList[i];
				item.el.visible = true;
				
				target.addElement(item.el);
			}
			
			this._blurFilter = new BlurFilter(10, 10);
			this._animateFilter = new AnimateFilter(target, this._blurFilter);
			this._animateFilter.duration = duration-(duration*0.3);
			this._animateFilter.play();
		}
		
		//----------------------------------
		//  addGroup
		//----------------------------------
		/**
		 *  Ao termino da animação de entrada de icones todos os elementos são 
		 *  movidos para outro tipo de grupo. 
		 * 
		 *  @return void
		 */		
		private function addGroup(event:Event):void
		{
			var len:Number	= this._elementList.length-1;	
			
			//Cria eventos de animação para cada elemento da lista			
			for (var i:Number = 0; i <= len; i++) 
			{
				var item:* = this._elementList[i];
				item.el.visible = true;
				item.el.x = item.x;
				item.el.y = item.y;
				
				this._group.addElement(item.el);
			}
		}
		
		//----------------------------------
		//  reverse
		//----------------------------------
		/**
		 *  Inverte a ordem dos elementos
		 * 
		 *  @return void
		 */		
		public function reverse():void
		{
			//Cria lista de botões
			this._elementList = this._elementList.reverse();
		}
		
	}
}